home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource5 / 363_01 / codegen.c < prev    next >
C/C++ Source or Header  |  1991-12-16  |  9KB  |  227 lines

  1. /***********************************************************************
  2.  *
  3.  *      CODEGEN.C
  4.  *      Code Generation Routines for 68020 Assembler
  5.  *
  6.  *    Function: output()
  7.  *      Places the data whose size and value are specified onto the output 
  8.  *      stream at the current location contained in global variable loc. That 
  9.  *      is, if a listing is being produced, it calls listObj() to print the 
  10.  *      data in the object code field of the current listing line; if an
  11.  *      object file is being produced, it calls outputObj() tooutput the data 
  12.  *      in the form of S-records. 
  13.  *
  14.  *      effAddr()
  15.  *      Computes the 6-bit effective address code used by the 68020 in most 
  16.  *      cases to specify address modes. This code is returned as the value of 
  17.  *      effAddr(). The desired addressing mode is determined by the field of 
  18.  *      the opDescriptor which is pointed to by the operand argument. The 
  19.  *      lower 3 bits of the output contain the register code and the upper 
  20.  *      3 bits the mode code. 
  21.  *
  22.  *      extWords()
  23.  *      Computes and outputs (using output()) the extension words for the 
  24.  *      specified operand. The generated extension words are determined from 
  25.  *      the data contained in the opDescriptor pointed to by the op argument 
  26.  *      and from the size code of the instruction, passed in the size argument.
  27.  *      The errorPtr argument is used to return an error code by the standard 
  28.  *      mechanism. 
  29.  *
  30.  *   Usage: output(int data, int size)
  31.  *
  32.  *      effAddr(opDescriptor *operand)
  33.  *
  34.  *      extWords(opDescriptor *op, int size, int *errorPtr)
  35.  *
  36.  *      Author: Paul McKee
  37.  *      ECE492    North Carolina State University, 12/13/86
  38.  *
  39.  *  Modified A.E. Romer. Version 1.0
  40.  *      17 March 1991:  ANSI functions, braces layout.
  41.  *      8 May 1991:     68020-specific effective address modes added to
  42.  *                      effAddr().
  43.  *      9 May 1991:     68020-specific extension words.
  44.  *
  45.  ************************************************************************/
  46.  
  47.  
  48. #include <stdio.h>
  49. #include "asm.h"
  50.  
  51. extern long loc;
  52. extern char pass2;
  53. extern FILE *listFile;
  54.  
  55. extern char listFlag;                       /* True if a listing is desired */
  56. extern char objFlag;              /* True if an object code file is desired */
  57.  
  58.  
  59. int output(long data, int size)
  60.     {
  61.  
  62.     if (listFlag)
  63.         listObj(data, size);
  64.     if (objFlag)
  65.         outputObj(loc, data, size);
  66.  
  67.     return NORMAL;
  68.     }
  69.  
  70.  
  71. int effAddr(opDescriptor *operand)
  72.     {
  73.     switch (operand->mode)
  74.         {
  75.         case DnDirect:          return 0x00 | operand->reg;
  76.         case AnDirect:          return 0x08 | operand->reg;
  77.         case AnInd:             return 0x10 | operand->reg;
  78.         case AnIndPost:         return 0x18 | operand->reg;
  79.         case AnIndPre:          return 0x20 | operand->reg;
  80.         case AnIndDisp:         return 0x28 | operand->reg;
  81.         case AnIndIndex:
  82.         case MemIndPostinx:
  83.         case MemIndPreinx:      return 0x30 | operand->reg;
  84.         case AbsShort:          return 0x38;
  85.         case AbsLong:           return 0x39;
  86.         case PCDisp:            return 0x3A;
  87.         case PCIndex:
  88.         case PCMemIndPostinx:
  89.         case PCMemIndPreinx:    return 0x3B;
  90.         case Immediate:         return 0x3C;
  91.  
  92.         default:    printf("INVALID EFFECTIVE ADDRESSING MODE!\n");
  93.                     exit (0);
  94.         }
  95.     }
  96.  
  97. int extWords(opDescriptor *op, int size, int *errorPtr)
  98.  
  99. /* The anding of data with 0xFFFF or 0xFF below is supefluous, I think.
  100.  * I believe it is done again in output() */
  101.  
  102.     {
  103.     long disp;
  104.     
  105.     switch (op->mode)
  106.         {
  107.         case DnDirect:          /* Dn */
  108.         case AnDirect:          /* An or SP */
  109.         case AnInd:             /* (An) or (SP) */
  110.         case AnIndPost:         /* (An)+ or (SP)+ */
  111.         case AnIndPre:          /* -(An) or -(SP) */
  112.             break;                      /* no extension words required */
  113.  
  114.         case AnIndDisp:         /* (<data>,An) */
  115.                         if (pass2)
  116.                             {
  117.                             disp = op->data;
  118.                             output(disp & 0xFFFF, WORD);
  119.                             if (disp < -32768 || disp > 32767)
  120.                                 NEWERROR(*errorPtr, INV_DISP);
  121.                             }
  122.                         loc += 2;
  123.                         break;
  124.  
  125.         case PCDisp:            /* (<data>,PC) */
  126.                         if (pass2)
  127.                             {
  128.                             disp = op->data - loc;
  129.                             output(disp & 0xFFFF, WORD);
  130.                             if (disp < -32768 || disp > 32767)
  131.                                 NEWERROR(*errorPtr, INV_DISP);
  132.                             }
  133.                         loc += 2;
  134.                         break;
  135.  
  136.         case AnIndIndex:        /* (<data>,An,Xn.SIZE*SCALE) */
  137.         case MemIndPostinx:     /* ([bd,An],Xn,od) */
  138.         case MemIndPreinx:      /* ([bd,An,Xn],od) */
  139.         case PCIndex:           /* (<data>,PC,Xn.SIZE*SCALE) */
  140.         case PCMemIndPostinx:   /* ([bd,PC],Xn,od) */
  141.         case PCMemIndPreinx:    /* ([bd,An,Xn],od) */
  142.                         if (pass2)
  143.                             output(op->xtenWord, WORD);
  144.                         if (op->xtenWord & FULL_FORMAT)
  145.                             {
  146.                             if ((op->xtenWord & BASE) == BASE_LONG)
  147.                                 {
  148.                                 if (pass2)
  149.                                     output(op->data, LONG);
  150.                                 loc +=4;
  151.                                 } 
  152.                             if ((op->xtenWord & BASE) == BASE_WORD)
  153.                                 {
  154.                                 if (pass2)
  155.                                     output(op->data, WORD);
  156.                                 loc +=2;
  157.                                 }
  158.                             if ((op->xtenWord & OUTER) == OUTER_LONG)
  159.                                 {
  160.                                 if (pass2)
  161.                                     output(op->outDisp, LONG);
  162.                                 loc +=4;
  163.                                 } 
  164.                             if ((op->xtenWord & OUTER) == OUTER_WORD)
  165.                                 {
  166.                                 if (pass2)
  167.                                     output(op->outDisp, WORD);
  168.                                 loc +=2;
  169.                                 }
  170.                             }
  171.                         loc += 2;
  172.                         break;
  173.  
  174.         case AbsShort:          /* <data>.W */
  175.                         if (pass2)
  176.                             {
  177.                             output(op->data & 0xFFFF, WORD);
  178.                             if (op->data < -32768 || op->data > 32767)
  179.                                 NEWERROR(*errorPtr, INV_ABS_ADDRESS);
  180.                             }
  181.                         loc += 2;
  182.                         break;
  183.  
  184.         case AbsLong:           /* <data>.L */
  185.                         if (pass2)
  186.                             output(op->data, LONG);
  187.                         loc += 4;
  188.                         break;
  189.  
  190.         case Immediate:         /* #<data> */
  191.                         if (!size || size == WORD)
  192.                             {
  193.                             if (pass2)
  194.                                 {
  195.                                 output(op->data & 0xFFFF, WORD);
  196.                                 if (op->data > 0xffff)
  197.                                     NEWERROR(*errorPtr, INV_16_BIT_DATA);
  198.                                 }
  199.                             loc += 2;
  200.                             break;
  201.                             }
  202.                         else if (size == BYTE)
  203.                             {
  204.                             if (pass2)
  205.                                 {
  206.                                 output(op->data & 0xFF, WORD);
  207.                                 if (op->data < -32768 || op->data > 32767)
  208.                                     NEWERROR(*errorPtr, INV_8_BIT_DATA);
  209.                                 }
  210.                             loc += 2;
  211.                             }
  212.                         else if (size == LONG)
  213.                             {
  214.                             if (pass2)
  215.                                 output(op->data, LONG);
  216.                             loc += 4;
  217.                             }
  218.                         break;
  219.         default:
  220.                     printf("INVALID EFFECTIVE ADDRESSING MODE!\n");
  221.                     exit(0);
  222.         }
  223.  
  224.     return NORMAL;
  225.     }
  226.  
  227.